package net.fpeg.kotlin.msa.wordbase.service

import net.fpeg.kotlin.msa.wordbase.dao.WordUserRelationDao
import net.fpeg.kotlin.msa.wordbase.dao.WordUserRelationGroupDao
import net.fpeg.kotlin.msa.wordbase.dto.WordGroupInitDto
import net.fpeg.kotlin.msa.wordbase.entity.Word
import net.fpeg.kotlin.msa.wordbase.entity.WordUserRelation
import net.fpeg.kotlin.msa.wordbase.entity.WordUserRelationGroup
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import javax.transaction.Transactional


@Service
class WordUserRelationService {
    @Autowired
    lateinit var wordUserRelationDao: WordUserRelationDao

    @Autowired
    lateinit var wordUserRelationGroupDao: WordUserRelationGroupDao

    @Autowired
    lateinit var wordService: WordService

    @Autowired
    lateinit var wordUserService: WordUserService

    @Autowired
    lateinit var wordUserRelationTypeService: WordUserRelationTypeService

    private fun getGroup(groupId: Long) =
            wordUserRelationGroupDao.getById(groupId)

    private fun getOneGroup(groupId: Long) =
            getGroup(groupId) ?: throw Exception("组不存在")

    fun findGroup(uid: Long, wordValue: String) = wordUserRelationGroupDao.findByWordUser_IdAndWordUserRelations_Word_Value(uid, wordValue)

    fun find(uid: Long, typeId: Long) = wordUserRelationDao.findByWordUserRelationType_Id(typeId)
    private fun addGroup(userId: Long) =
            wordUserRelationGroupDao.save(WordUserRelationGroup(
                    null,
                    wordUserService.getOne(userId)
            ))

    private fun deleteGroup(groupId: Long) {
        wordUserRelationGroupDao.delete(getOneGroup(groupId))
    }

    fun get(id: Long) = wordUserRelationDao.getById(id)
    fun getOne(id: Long) = get(id) ?: throw Exception("不存在的")

    /**
     * 根据单词初始化组
     *
     * @param wordValue 单词值
     * @return 组id
     */
    fun init(uid: Long, wordValue: String) =
            addGroup(uid).let { group ->
                WordUserRelation(
                        null,
                        wordService.getOne(wordValue),
                        wordUserService.getOne(uid).defaultRelationType ?: throw Exception("未知错误"),
                        group
                ).let {
                    wordUserRelationDao.save(it)
                    WordGroupInitDto(
                            it.id ?: throw Exception("未知错误"),
                            group.id ?: throw Exception("未知错误")
                    )
                }
            }

    /**
     * 向组里添加单词时态
     *
     * @param wordValue
     */
    fun add(uid: Long, groupId: Long, wordValue: String, typeId: Long) =
            wordUserRelationDao.save(WordUserRelation(
                    null,
                    wordService.add(wordValue),
                    wordUserRelationTypeService.getOne(typeId),
                    getOneGroup(groupId)
            ))

    fun edit(uid: Long, id: Long, wordValue: String, typeId: Long) =
            getOne(id)
                    .apply {
                        word = wordService.getOne(wordValue)
                        wordUserRelationType = wordUserRelationTypeService.getOne(typeId)
                    }
                    .let { wordUserRelationDao.save(it) }

    @Transactional
    fun remove(uid: Long, id: Long) =
            wordUserRelationDao.deleteById(id)


    /**
     * 根据单词组找到组ids
     * @param wordValues
     * @return
     */
    fun fetchGroupIdByWordIn(uid: Long, words: Set<Word>) =
            wordUserRelationDao.findDistinctWordUserRelationGroupByWordInAndWordUserRelationGroup_WordUser_Id(
                    words,
                    uid
            ).map { it.wordUserRelationGroup.id }.toSet()

    /**
     * 根据组id找到tenses
     *
     * @param id 组id
     * @return tenses
     */
    fun findTenseByGroupId(groupId: Long) = wordUserRelationDao.findByWordUserRelationGroup_Id(groupId)

}